package ido.com.util;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Scanner;
import java.util.StringTokenizer;

import com.google.gdata.client.GoogleService;
import com.google.gdata.data.DateTime;
import com.google.gdata.data.Entry;
import com.google.gdata.data.Feed;
import com.google.gdata.data.Person;
import com.google.gdata.client.Query;
import com.google.gdata.data.PlainTextConstruct;
import com.google.gdata.data.extensions.EventEntry;
import com.google.gdata.data.extensions.EventFeed;
import com.google.gdata.data.extensions.When;
import com.google.gdata.util.ServiceException;
import javax.swing.JTextArea;

/**
 * Working with: GCAL API
 * 1. Clean all the events 
 * 2. Parse the page from: iteamwork 
 * 3. Add all the events. 
 * 4. Add events to Gannt view page.
 * 
 * @author green ido
 * http://idojava.blogspot.com/
 */
public class GCal {

    public static final String CAL_URL = "http://www.google.com/calendar/feeds/" +
                  FileUtil.sharedInstance.getProperty("gmail-id") +" /private/full";
    public static final String GANNT_FILE = "/var/www/gcal/timeline_sa/xml/timeline.xml";
    private final String passwd;
    private URL feedUrl;
    private GoogleService myService;
    private Hashtable<String, String> shortMonths = new Hashtable<String, String>();
    private Hashtable<String, String> noMonths = new Hashtable<String, String>();

    /**
     * Set up the URL and the object that will handle the connection
     * @throws MalformedURLException
     */
    public GCal() throws Exception {
        initMonths();
        passwd = FileUtil.sharedInstance.getProperty("passwd", "");
        feedUrl = new URL(CAL_URL);
        myService = new GoogleService("cl", "dev-cal");
        myService.setUserCredentials(FileUtil.sharedInstance.getProperty("gmail-id"), 
                passwd);
    }

    private void initMonths() {
        shortMonths.put("Jan", "January");
        shortMonths.put("Feb", "February");
        shortMonths.put("Mar", "March");
        shortMonths.put("Apr", "April");
        shortMonths.put("May", "May");
        shortMonths.put("Jun", "June");
        shortMonths.put("Jul", "July");
        shortMonths.put("Aug", "August");
        shortMonths.put("Sep", "September");
        shortMonths.put("Oct", "October");
        shortMonths.put("Nov", "November");
        shortMonths.put("Dec", "Devember");

        noMonths.put("Jan", "01");
        noMonths.put("Feb", "02");
        noMonths.put("Mar", "03");
        noMonths.put("Apr", "04");
        noMonths.put("May", "05");
        noMonths.put("Jun", "06");
        noMonths.put("Jul", "07");
        noMonths.put("Aug", "08");
        noMonths.put("Sep", "09");
        noMonths.put("Oct", "10");
        noMonths.put("Nov", "11");
        noMonths.put("Dec", "12");

    }

    /**
     * 
     * @throws Exception
     */
    public void setFeed() throws Exception {
        // Mark the feed as an Event feed:
        new EventFeed().declareExtensions(myService.getExtensionProfile());

        // Send the request and receive the response:
        Feed myFeed = myService.getFeed(feedUrl, Feed.class);
    // System.out.println("myFeed: "+ myFeed);
    }

    public String getMonthNo(String name) {
        return noMonths.get(name);
    }

    /**
     * 
     * @param name
     * @return
     */
    public String getMonthName(String name) {
        return shortMonths.get(name);
    }

    /**
     * 
     * @param event
     * @throws IOException
     * @throws ServiceException
     */
    public void insertItem(GCalEvent event) throws IOException,
            ServiceException {
        EventEntry myEntry = new EventEntry();
        myEntry.setTitle(new PlainTextConstruct(event.getTitle()));
        myEntry.setContent(new PlainTextConstruct(event.getDesc()));
        Person author = new Person("Ido", null, "http://idojava.blogspot.com");
        myEntry.getAuthors().add(author);
        // 2006-04-17T15:00:00-08:00
        String tmpTime = event.getDate();
        StringTokenizer st = new StringTokenizer(tmpTime, " ");
        ArrayList<String> parts = new ArrayList<String>();
        while (st.hasMoreTokens()) {
            parts.add(st.nextToken());
        }
        String month = getMonthNo(parts.get(0));
        String day = parts.get(1);
        if (day.length() < 2) {
            day = "0" + day;
        }
        String year = "20" + parts.get(2);
        DateTime startTime = DateTime.parseDateTime(year + "-" + month + "-" + day + "T08:00:00-08:00");
        DateTime endTime = DateTime.parseDateTime(year + "-" + month + "-" + day + "T09:00:00-08:00");

        When eventTimes = new When();
        eventTimes.setStartTime(startTime);
        eventTimes.setEndTime(endTime);
        myEntry.addTime(eventTimes);

        // Send the request and receive the response:
        EventEntry insertedEntry = myService.insert(feedUrl, myEntry);

        /**
         * save the entry to the xml-gannt chart <data> <event start="February
         * 14 2008 09:00" title="'Top Five Reviews' page - moshe (tcc_v1)"> 'Top
         * Five Reviews' page - moshe (tcc_v1) </event>
         */
        String eventXML = "<event start=" + getMonthName(parts.get(0)) + " " + day +
                " " + year + "08:00 title=" + event.getDesc() +
                ">" + event.getDesc() + "</event>";
        FileUtil.sharedInstance.writeToFile(GANNT_FILE, eventXML);

    }

    public int queryCal(String searchFor) throws Exception {
        return queryCal(searchFor, null);
    }

    /**
     * 
     * @param searchFor
     * @return
     * @throws Exception
     */
    public int queryCal(String searchFor, JTextArea statusArea) throws Exception {
        Query myQuery = new Query(feedUrl);
        myQuery.setFullTextQuery(searchFor);
        Feed myResultsFeed = myService.query(myQuery, Feed.class);
        int i;
        for (i = 0; i < myResultsFeed.getEntries().size(); i++) {
            Entry updatedEntry = myResultsFeed.getEntries().get(i);
            String myEntryTitle = updatedEntry.getTitle().getPlainText();
            String str = i + ") Removing event: " + myEntryTitle + " link: " + updatedEntry.getEditLink().getHref();
                System.out.println(str);
            if (statusArea != null) {
                statusArea.setText(statusArea.getText()+ str + "\n");
                statusArea.repaint();
            }
            URL deleteUrl = new URL(updatedEntry.getEditLink().getHref());
            myService.delete(deleteUrl);
        }
        return i;
    }

    /**
     * Simple unit test    
     * Working with: GCAL 1. Clean all the events (make with tcc_v1)
     * 2. Parse the page from: iteamwork 3. Add all the events.
     * 
     * @param args
     */
    public static void main(String[] args) {
        try {
            System.out.println("--Start");
            GCal gcal = new GCal();
            gcal.setFeed();
           
            int j = 0;
            int i = gcal.queryCal("TCC v1.0");
            // because it take more the one time to remove all the events...
            while (j < 4 && i > 0) {
                i = gcal.queryCal("TCC v1.0");
            }
            
            //System.out.println("Check the GCal online and see if it's clean.\nNow, do it?");
            //Scanner in = new Scanner(System.in);
            String rc = "yes"; //in.nextLine();
            if (rc.equalsIgnoreCase("yes") || rc.equalsIgnoreCase("y")) {
                ParsePlan parser = new ParsePlan();
                parser.parsePage("http://www.iteamwork.com/cgi-bin/cgii/tw.tasks?pid=100318");          
                i = 0;
                FileUtil.sharedInstance.writeToFile(GANNT_FILE, "<data>");
                ArrayList<GCalEvent> events = parser.getEvents();
                for (GCalEvent calEvent : events) {
                    gcal.insertItem(calEvent);
                    System.out.println((i++) + ") event: " + calEvent);
                }
                FileUtil.sharedInstance.writeToFile(GANNT_FILE, "</data>");
            } else {
                System.out.println("ok not update of GCal this time.\nbye bye");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("--End");
    }
}
